package com.dc.designPattern._19_interpreter.impl;

import com.google.common.base.Throwables;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Map;

/**
 * Description: 解释器模式_客户端
 *
 * 通过解释器模式来实现四则运算，如计算 a+b-c 的值，具体要求
 *     1) 先输入表达式的形式，比如 a+b+c-d+e, 要求表达式的字母不能重复
 *     2) 在分别输入 a ,b, c, d, e 的值
 *
 * @author: gdc
 * @date: 2021/6/8
 * @version 1.0
 */
@Slf4j
public class Client {

    public static void main(String[] args){
        try {
            while (true) {
                // step 1 获取表达式，例如：a+b
                String expStr = getExpStr();
                if ("quit".equals(expStr)) {
                    break;
                }

                // step 2 获取表达式参数值对应
                Map<String, Integer> var = getValue(expStr);

                Calculator calculator = new Calculator(expStr);
                System.out.println("运算结果为：" + calculator.run(var));
            }
        } catch (IOException e) {
            log.error("出现异常信息为：{}", Throwables.getStackTraceAsString(e));
        }
    }


    /**
     * 获取 表达式
     *
     * @return          结果
     */
    private static String getExpStr() throws IOException {
        System.out.println("请输入表达式 (退出输入quit)：");
        return new BufferedReader(new InputStreamReader(System.in)).readLine();
    }

    /**
     * 根据表达式获取值
     * @param expStr    表达式
     * @return
     * @throws IOException
     */
    private static Map<String, Integer> getValue(String expStr) throws IOException {
        Map<String, Integer> result = Maps.newHashMap();

        for (char ch : expStr.toCharArray()) {
            if('+' != ch && '-' != ch){
                if (!result.containsKey(String.valueOf(ch))) {
                    System.out.println("请输入【" + ch + "】的值");
                    String in = new BufferedReader(new InputStreamReader(System.in)).readLine();
                    result.put(String.valueOf(ch), Integer.valueOf(in));
                }
            }
        }
        return result;
    }
}
